#if USE_BESTHTTP
using BestHTTP.WebSocket;
#endif

using System;
using UnityEngine;

namespace SinceTimes.NetWork
{
    public class ConnectionHttpWebSocket : Connection
    {
        public ConnectionHttpWebSocket(MonoBehaviour owner) : base(owner)
        {

        }


#if USE_BESTHTTP

        public  WebSocket WS;

        public override float Latency => 0;// WS!=null&& WS.IsOpen? WS.Latency/1000f :0;

        byte[] _BUFF = new byte[4096];


        public override bool Connected => WS != null && WS.State == WebSocketStates.Open;


        public override string State => WS != null ? WS.State.ToString() : "NULL";



        protected override void _DoConnect() => _ConnectAsync();//Owner.StartCoroutine(_Conntect_Runer()); 


        void _ConnectAsync()
        {
            string url = Url;

            if (Port > 0)
                url = $"{url}:{Port}";

            Uri uri = new Uri(url);


            WS = new WebSocket(uri)
            {
                OnOpen = _OnOpen,
                OnBinary = _OnBinary,
                OnError= (ws,r)=>
                {
                    Error = r;
                    _DoClose(true);
                },
                OnClosed=(ws,code,r)=>
                {
                    Error = $"[{code}]:{r}";
                    _DoClose();
                },
             
            };

            WS.Open();
            if (Net.SHOWLOG) Debug.Log($"[ConnectionHttpWebSocket.WS.Open({uri})].................");


          
        }


        void _OnOpen(WebSocket ws)
        {
            if (!ws.IsOpen) return;
            if (Net.SHOWLOG) Debug.Log($"[ConnectionHttpWebSocket.WS._OnOpen({ws.IsOpen})].................");


            //如果有身份验证...
            if (_Buff_Authenticate != null && _Buff_Authenticate.Length > 0)
            {
                //发送身份验证
                ws.Send(_Buff_Authenticate);
                if (Net.SHOWLOG) Debug.Log($"[WS.SendAsync(_Buff_Authenticate)]SendAsync:_Buff_Author:{Net.BYTES_STRING(_Buff_Authenticate)}");


                if (UserAuthCheckable)
                {
                    // 需要等待身份验证...
                    ws.OnBinary = _OnBinary_Authenticate;

                }
                else
                {

                    //启动正常 接受回调...
                    ws.OnBinary = _OnBinary;
                    OnConnectSuccess();
                }


            }
            else//不需要身份验证...直接正常启动链接成功....
            {
                //启动正常 接受回调...
                ws.OnBinary = _OnBinary;
                OnConnectSuccess();
            }


        }

        protected override void _DoClose(bool callback = false)
        {
            if (WS != null && WS.IsOpen)
                WS.Close();
            base._DoClose(callback);
        }
        //接受身份验证逻辑包..
        void _OnBinary_Authenticate(WebSocket ws, byte[] data)
        {
            if (Net.SHOWLOG) Debug.Log($"[ConnectionHttpWebSocket.WS._OnBinary_Authenticate({Net.BYTES_STRING(data)})].................");
            //如果包 合法
            if (data.Length > 0)
            {
                ushort len = Net.BYTE_USHORT(data, 0); //消息报长度
                ushort type = Net.BYTE_USHORT(data, 2);//消息类型

                if ( type == 20002)
                {
                    Error = "";

                    //启动正常 接受回调...
                    ws.OnBinary = _OnBinary;
                    OnConnectSuccess();

                    return;
                }
            }

            _DoClose(true);
        }

        protected override void OnConnectSuccess()
        {
            base.OnConnectSuccess();
        }

        //接受正常逻辑包..
        void _OnBinary(WebSocket webSocket, byte[] data)
        {

            if (Net.SHOWLOG)Debug.Log($"[ConnectionHttpWebSocket.WS._OnBinary]:data[{data.Length}].................");

            if (data == null || data.Length < 1)
            {
                _DoClose(true);
                return;
            }

            RuntimeState.Receiving = true;
            _OnReceive(data, 0, (uint)data.Length);
        }


        protected override int _DoSend(byte[] data)
        {
            try
            {
                WS.Send(data);
                _OnSend(data);
                return data.Length;
            }
            catch(Exception e)
            {
                Error = e.Message;
                _DoClose(true);return 0;
            }

           
        }

        protected override void RuntimeCheck()
        {
            base.RuntimeCheck();

            RuntimeState.State = (WS != null ? WS.State.ToString() : "null");

        }

#endif
    }

}
